//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2003 Intrinsyc Europe Ltd.
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004 Siemens AG
//
// Version: 1.1.2.5
// Date:    11. Jan. 2006
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
//
//                       -----------------------------
//                       Documentation Powermanagement
//                       -----------------------------
//
// The RIL driver supports 2 different interfaces for changes of the module's
// power state which are completely independent of each other from the
// external point of view. The 1st interface is the Windows power management
// interface and the 2nd is the RIL equipment state interface. The class
// CPowerManager handles the internal dependencies of these 2 supported
// interfaces, synchronizes possible overlapping calls of the interfaces and
// executes the module's power state transitions.
// To enable the RIL driver's power management the compiler flag
// "RIL_ENABLE_POWER_HANDLING" must be set.
//
//
// The equipment state interface
// -----------------------------
// The RIL driver supports the following equipment states where changes from
// any state to any other are possible:
//  - RIL_EQSTATE_MINIMUM
//    The module is completely switched off.
//  - RIL_EQSTATE_FULL
//    The module is completely switched on.
//  - RIL_EQSTATE_DISABLETXANDRX
//    The module is switched to airplane mode which means that the radio part
//    of the module is switched off but the module remains powered on. If the
//    connected module doesn't support the airplane mode it is switched to
//    RIL_EQSTATE_MINIMUM automatically.
// Calls of the equipment state interface via IOCTL_RIL_SETEQUIPMENTSTATE are
// nonblocking which means that the call returns as soon as possible. The
// module state change is handled via an internal command queue in background.
// After the module power state change has finished the corresponding
// RIL_NOTIFY_RADIOEQUIPMENTSTATECHANGED is broadcasted.
// Equipment state changes are only allowed in the system power state D0. If
// the RIL driver is in any other power state than D0 calls of the equipment
// state interface are rejected.
// Because there is not always a clear correlation between the power state
// and the equipment state possible (e.g. the equipment state
// RIL_EQSTATE_DISABLETXANDRX doesn't necessarily correspond to any power
// state and the power state D3 doesn't necessarily correspond to any
// equipment state) the RIL's power state remains unmodified on changes of the
// equipment state.
//
//
// The default power management interface
// --------------------------------------
// The RIL driver supports the power states D0 (full operation), D3 (suspend)
// and D4 (full off). The RIL registers for the power states D1 and D2 as well
// but handles these power states the same as D0 in the default power handling.
// Power state changes to the states D0, D1 and D2 are handled non blocking via
// the internal power command queue but with higher priority than equipment
// state changes. Power state changes to D3 and D4 are blocking. Otherwise
// cannot be guaranteed that the module has finished a possible state change
// before the system suspends or shuts down.
// If a power state change causes a change of the equipment state the
// corresponding RIL_NOTIFY_RADIOEQUIPMENTSTATECHANGED is broadcasted as well.
// As mentioned already in the description of the equipment state interface
// calls of this equipment state interface are only allowed in the power state
// D0. Possibly queued equipment change requests are removed from the power
// command queue after a power state change to any other value than D0.
//
// The following table describes the executed actions for power state
// transitions (PST) from higher to lower power levels which depend on the
// current equipment state (CES).
//
// ===========================================================================
// PST     |  CES      |  Action
// ===========================================================================
// D0->D3  |  Full     |  Disable cyclic URCs
//         |           |  (leave call, sms and registration URCs enabled)
//         |  RxTxOff  |  Disable cyclic URCs
//         |           |  (leave call, sms and registration URCs enabled)
//         |  Minimum  |  Nothing
// ---------------------------------------------------------------------------
// D0->D4  |  Full     |  Switch to equipment state minimum
//         |  RxTxOff  |  Switch to equipment state minimum
//         |  Minimum  |  Nothing
// ---------------------------------------------------------------------------
// D3->D4  |  Full     |  Switch to equipment state minimum
//         |  RxTxOff  |  Switch to equipment state minimum
//         |  Minimum  |  Nothing
// ---------------------------------------------------------------------------
//
// The following table describes the executed actions for power state
// transitions (PST) from lower to higher power levels which depend on the
// last equipment state (LES) stored before the power state transition from
// high to low.
//
// ===========================================================================
// PST     |  LES      |  Action
// ===========================================================================
// D4->D3  |  Full     |  Switch to equipment state full, disable cyclic URCs
//         |           |  (leave call, sms and registration URCs enabled)
//         |  RxTxOff  |  Switch to equipment state RxTxOff
//         |  Minimum  |  Nothing
// ---------------------------------------------------------------------------
// D4->D0  |  Full     |  Switch to equipment state full
//         |  RxTxOff  |  Switch to equipment state RxTxOff
//         |  Minimum  |  Nothing
// ---------------------------------------------------------------------------
// D3->D0  |  Full     |  Switch to equipment state full
//         |  RxTxOff  |  Switch to equipment state RxTxOff
//         |  Minimum  |  Nothing
// ---------------------------------------------------------------------------
//
//
// The customer power management interface
// ---------------------------------------
// The default power management behaviour described in the last paragraph can
// be overruled if required. To achieve this the RIL driver calls the RHA
// function RHA_SystemPowerChange() on each power state change before the
// default power state change is executed. The exact usage of this function
// is described later in this paragraph. The general rule is that a customer
// RHA implementation can return the desired module state in this function or
// continue with the default power management by returning the default value.
// The RHA_SystemPowerChange() overrides the default power management behaviour
// of the RIL driver without any further validation checks. That means if the
// function returns any other value than the default value the module will be
// switched into that state. Following from that rule a customer RHA
// implementation which overrides the default power management when the power
// state is raised must take care of the LastEquipmentState registry flag on
// it's own if required.
// The exact syntax of the RHA_SystemPowerChange() function is as follows:
// DWORD RHA_SystemPowerChange(CEDEVICE_POWER_STATE  CurrPwrState,
//                             CEDEVICE_POWER_STATE  NewPwrState,
//                             DWORD                 dwCurrModuleState,
//                             DWORD                 dwNewDefaultModuleState,
//                             BOOL                  fOngoing,
//                             BOOL                  fQuery)
// Parameter:
//   CurrPwrState:
//     The current power state.
//   NewPwrState:
//     The requested new power state.
//   dwCurrModuleState:
//     The current module state.
//   dwNewDefaultModuleState:
//     The new module state the RIL will use if not overwqritten by the
//     return value of RHA_SystemPowerChange(). To use the RIL default power
//     management simply return the value passed in this parameter.
//   fOngoing:
//     Because most module state transintions are handled asynchronously in
//     background it is possible that a state transition is in progress when
//     the system changes the power state and RHA_SystemPowerChange() is
//     called. That situation is signaled with this parameter.
//   fQuery:
//     A flag indicating if the power state change is actually requested
//     (FALSE) or the RIL called the function only for information (TRUE).
//     During system start some arrays with the internal power management
//     capabilities must be passed to the system. During this power capability
//     check the RIL will call RHA_SystemPowerChange() to query the
//     implemented power state changes without any power state executed.
//     The RIL will call RHA_SystemPowerChange() first for a power state
//     change D4->D0 to query the required modem state in the power state D0
//     and then in a loop the power state changes D4->D0, D3->D0, D2->D0 and
//     D1->D0. Beacuse that power capability check is done only once during
//     system start the system might rely on wrong values if the power
//     management behaviour implemented in RHA_SystemPowerChange() changes
//     during runtime. In case of a query call RHA_SystemPowerChange() must not
//     evaluate the LastEquipmentState registry flag and assume that the last
//     equipment state is "RIL_EQSTATE_FULL" so that the RIL driver can fill
//     the power capability arrays properly.
// Return value:
//   The new module state requested for the given power state change. If this
//   is another than the default value the module will be switched into that
//   state without any further checking as mentioned above.
//
//
// The supported module states
// ---------------------------
// The following list describes the supported module states realized as a
// series of defindes which are used for the parameter "dwCurrModuleState" and
// have to be used for the return value of RHA_SystemPowerChange():
//   MODEMSTATE_SIEMENS_FORCE_POWEROFF:
//     That value doesn't represent a module state directly. It is used to
//     turn off completely by immediately switching off the power without a
//     graceful shutdown via AT^SMSO. The resulting module state will be
//     "MODEMSTATE_SIEMENS_POWEROFF".
//   MODEMSTATE_SIEMENS_POWEROFF:
//     The module is turned completely off.
//   MODEMSTATE_SIEMENS_AIRPLANE:
//     The module is in airplane mode with the radio interface disabled. In
//     that state all except the emergency URCs are disbled implicitly.
//   MODEMSTATE_SIEMENS_POWERON:
//     The module is in full operation mode with all URCs and the radio
//     interface enabled.
//   MODEMSTATE_SIEMENS_URCCONFIG_CALL:
//     The module is in full operation mode with the radio interface
//     enabled but with only the call and emergency URCs enabled.
//   MODEMSTATE_SIEMENS_URCCONFIG_CALL_SMS:
//     The module is in full operation mode with the radio interface
//     enabled but with only the call, sms and emergency URCs enabled.
//     This is the default module state for the default power management.
//   MODEMSTATE_SIEMENS_URCCONFIG_CALL_SMS_REG:
//     The module is in full operation mode with the radio interface
//     enabled but with only the call, sms, registration and emergency URCs
//     enabled.
//
//
// Example for RHA_SystemPowerChange() implementation
// --------------------------------------------------
// ////////////////////////////////////////////////////////////////////////////
// //
// // Simple example to overwrite the RIL default powermanagement with the
// // following modemstates:
// //   D0, D1  -> Use default handling
// //   D2      -> MODEMSTATE_SIEMENS_POWEROFF
// //   D3      -> MODEMSTATE_SIEMENS_POWEROFF
// //   D4      -> MODEMSTATE_SIEMENS_POWEROFF
// ////////////////////////////////////////////////////////////////////////////
// DWORD RHA_SystemPowerChange(CEDEVICE_POWER_STATE  CurrPwrState,
//                             CEDEVICE_POWER_STATE  NewPwrState,
//                             DWORD                 dwCurrModuleState,
//                             DWORD                 dwNewDefaultModuleState,
//                             BOOL                  fOngoing,
//                             BOOL                  fQuery) {
// MODEMSTATE dwNewModemState = dwNewDefaultModuleState;
//
//   switch(NewPwrState) {
//     case D0:
//     case D1:
//       // We don't want to overwrite the default handling for D0 and D1 so
//       // we don't have to deal with the last equipment state because the RIL
//       // does this in the default handling. For this reason we don't need to
//       // consider the query flag either. SImply return the new module state
//       // suggested by the RIL.
//       NewModemState = dwNewDefaultModuleState;
//       break;
//     case D2:
//       // In D2 we want to turn the module off, so we don't have to deal with
//       // the last equipment state becaue we want to have the module switched
//       // off in any case. For this reason we don't need to consider the
//       // query flag either.
//       // For another module state it must be checked if it fit's with the
//       // last equipment state flag for a non query call (e.g. the module
//       // shouldn't be switched on if the last equipemnt state was
//       // RIL_EQSTATE_MINIMUM).
//       NewModemState = MODEMSTATE_SIEMENS_POWEROFF;
//       break;
//     case D3:
//       // In D2 we have turned the module of, return the same state for D3 to
//       // avoid that the RIL possibly turns it on again in the default
//       // handling.
//       NewModemState = MODEMSTATE_SIEMENS_POWEROFF;
//       break;
//     case D4:
//       // In D2 we have turned the module off, return the same state for D3 to
//       // avoid that the RIL possibly turns it on again in the default
//       // handling.
//       NewModemState = MODEMSTATE_SIEMENS_POWEROFF;
//       break;
//   }
//
//   return NewModemState;
// }
//
//
// Unattended mode
// ---------------
// To improve user experience it is possible to configure the RIL driver via
// the compiler flag "RIL_ENABLE_UNATTENDED_HANDLING" to register for unattended
// mode during all non blocking modem state transitions. The unattended mode is
// a special power state where the system allows modules registered for the
// unattended mode to finsh time consuming operations in background with
// disabled user interface before entering the suspend mode.
//
//
// Restrictions of customer power management interface
// ---------------------------------------------------
// To provide the maximum possible flexibility a module state returned by a
// RHA_SystemPowerChange() is entered without any further examinations by the
// RIL driver as already mentioned above. That requires some care which has to
// be taken inside the RHA_SystemPowerChange() implementation because there
// might be some module state changes for a given power state change which
// lead to unexpected results. One example for a possible conflict is the
// change from MODEMSTATE_SIEMENS_POWEROFF to any of the URC configurations.
// A given URC configuration can only be enabled after the module has been
// booked into the network which might require the user input of the network
// PIN. Therefore the EnterPowerState() function cannot be blocked until the
// requested URC configuration has been reached as usual. Nevertheless the
// requested URC configuration will be entered after the network login has
// taken place. But if the described module state change (to be repeated:
// MODEMSTATE_SIEMENS_POWEROFF -> MODEMSTATE_SIEMENS_URCCONFIG_XXX) is
// requested when the system suspends or powers down that point might never
// be reached.
//
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//

#ifndef RHAAPI_H
#define RHAAPI_H TRUE

#ifdef __cplusplus
extern "C" {
#endif

#include <pm.h>

//
// The different module power states
//
#define MODEMSTATE_SIEMENS_MIN                           1
#define MODEMSTATE_SIEMENS_FORCE_POWEROFF                1
#define MODEMSTATE_SIEMENS_POWEROFF                      2
#define MODEMSTATE_SIEMENS_AIRPLANE                      3
#define MODEMSTATE_SIEMENS_POWERON                       4
#define MODEMSTATE_SIEMENS_URCCONFIG_CALL                5
#define MODEMSTATE_SIEMENS_URCCONFIG_CALL_SMS            6
#define MODEMSTATE_SIEMENS_URCCONFIG_CALL_SMS_REG        7
#define MODEMSTATE_SIEMENS_MAX                           7

//
// API types
//
typedef void (*PFNRHA_INIT_DEINIT)(void);
typedef BOOL (*PFNRHA_RADIO_POWER_ON)(void);
typedef BOOL (*PFNRHA_RADIO_POWER_OFF)(void);
typedef BOOL (*PFNRHA_IS_RADIO_POWER_ON)(void);
typedef BOOL (*PFNRHA_ACTIVATE_VOICE_PATH)(DWORD dwTxAudioMode, DWORD dwRxAudioMode);
typedef BOOL (*PFNRHA_DEACTIVATE_VOICE_PATH)(void);
typedef BOOL (*PFNRHA_ADJUST_TX_VOLUME)(DWORD dwAudioMode, DWORD dwVolume);
typedef BOOL (*PFNRHA_ADJUST_RX_VOLUME)(DWORD dwAudioMode, DWORD dwVolume);
typedef BOOL (*PFNRHA_GET_RHA_VERSION)(DWORD *pRHAVersion);
typedef BOOL (*PFNRHA_CONFIRM_AUDIO_MODE)(DWORD *dwTxAudioMode, DWORD *dwRxAudioMode);
typedef DWORD (*PFNRHA_SYSTEM_POWER_CHANGE)(CEDEVICE_POWER_STATE CurrPwrState, CEDEVICE_POWER_STATE NewPwrState, DWORD dwCurrModuleState, DWORD dwNewDefaultModuleState, BOOL fOngoing, BOOL fQuery);

typedef struct tagRHAFunctionList {
    PFNRHA_INIT_DEINIT              pfnRHA_Init;
    PFNRHA_INIT_DEINIT              pfnRHA_DeInit;
    PFNRHA_RADIO_POWER_ON           pfnRHA_RadioPwrOn;
    PFNRHA_RADIO_POWER_OFF          pfnRHA_RadioPwrOff;
    PFNRHA_IS_RADIO_POWER_ON        pfnRHA_IsRadioPwrOn;
    PFNRHA_ACTIVATE_VOICE_PATH      pfnRHA_ActivateVoicePath;
    PFNRHA_DEACTIVATE_VOICE_PATH    pfnRHA_DeactivateVoicePath;
    PFNRHA_ADJUST_TX_VOLUME         pfnRHA_AdjustTxVolume;
    PFNRHA_ADJUST_RX_VOLUME         pfnRHA_AdjustRxVolume;
    PFNRHA_GET_RHA_VERSION          pfnRHA_GetRHAVersion;
    PFNRHA_CONFIRM_AUDIO_MODE       pfnRHA_ConfirmAudioMode;
    PFNRHA_SYSTEM_POWER_CHANGE      pfnRHA_SystemPowerChange;
} RHA_FUNCTION_LIST, *PRHA_FUNCTION_LIST;

//
// API function names
//
#define RHA_INIT                    TEXT("RHA_Init")
#define RHA_DEINIT                  TEXT("RHA_DeInit")
#define RHA_RADIO_POWER_ON          TEXT("RHA_RadioPwrOn")
#define RHA_RADIO_POWER_OFF         TEXT("RHA_RadioPwrOff")
#define RHA_IS_RADIO_POWER_ON       TEXT("RHA_IsRadioPwrOn")
#define RHA_GET_RHA_VERSION         TEXT("RHA_GetRHAVersion")
#define RHA_ACTIVATE_VOICE_PATH     TEXT("RHA_ActivateVoicePath")
#define RHA_DEACTIVATE_VOICE_PATH   TEXT("RHA_DeactivateVoicePath")
#define RHA_ADJUST_TX_VOLUME        TEXT("RHA_AdjustTxVolume")
#define RHA_ADJUST_RX_VOLUME        TEXT("RHA_AdjustRxVolume")
#define RHA_CONFIRM_AUDIO_MODE      TEXT("RHA_ConfirmAudioMode")
#define RHA_SYSTEM_POWER_CHANGE     TEXT("RHA_SystemPowerChange")

#ifdef __cplusplus
}
#endif

#endif

